import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

// 输入框高度百分比
const double _scale = 0.7;
// 提示百分比
const double _tipScale = 0.3;
// 字体占用内容 百分比
const double _textFontScale = 0.755;
// 文字行高
const double _textHeight = 1.2;

// 文字占用内容百分比
const double _textScale = 0.5;

class ITextFiled extends StatefulWidget {
  final String hintText;
  final IconData preIcon;
  final double textWidth;
  final double textHeight;
  final bool obscureText;
  final String defaultStr;
  final bool showError;
  final BoxDecoration inputDecoration;
  final TextFiledValidata textFiledValidata;
  ITextFiled(this.textWidth, this.textHeight,
      {this.obscureText = false,
      this.hintText,
      this.preIcon,
      this.textFiledValidata,
      this.defaultStr,
      this.showError: true,
      this.inputDecoration});
  @override
  _ITextFiledState createState() => _ITextFiledState();
}

class _ITextFiledState extends State<ITextFiled> {
  TextEditingController _textEditingController =
      new TextEditingController(text: "");
  FocusNode _focusNode = new FocusNode();
  double maxHeight;
  BoxDecoration _inputDecoration;
  @override
  void initState() {
    // 当没有error 信息的时候  直接铺满 整个widget
    if (widget.showError) {
      maxHeight = widget.textHeight * _scale;
    } else {
      maxHeight = widget.textHeight;
    }
    if (widget.inputDecoration == null) {
      _inputDecoration = BoxDecoration(
        color: Colors.black.withOpacity(0.1),
      );
    } else {
      _inputDecoration = widget.inputDecoration;
    }
    _textEditingController.text = widget.defaultStr;
    _textEditingController.addListener(() {
      if (widget.textFiledValidata != null) {
        widget.textFiledValidata.error = null;
      }
      setState(() {});
    });
    if (widget.textFiledValidata != null) {
      if (widget.defaultStr != null && widget.defaultStr != "") {
        widget.textFiledValidata.show = true;
        widget.textFiledValidata.value = widget.defaultStr;
        widget.textFiledValidata.success =
            RegExp(widget.textFiledValidata.paretten)
                .hasMatch(widget.defaultStr);
      }
    }
    super.initState();
    _focusNode.addListener(() {
      if (_focusNode.hasFocus) {
        _focusNode.unfocus();

        showDialog<Null>(
            context: this.context,
            barrierDismissible: false,
            useSafeArea: false,
            builder: (BuildContext childContext) {
              var child = IFloatText(
                textWidth: widget.textWidth,
                hintText: widget.hintText,
                textHeight: widget.textHeight,
                defaultStr: widget.defaultStr,
                obscureText: widget.obscureText,
                textFiledValidata: widget.textFiledValidata,
                parentController: _textEditingController,
              );
              return child;
            });
      } else {}
    });
  }

  @override
  void dispose() {
    super.dispose();
    _focusNode.dispose();
    _textEditingController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      constraints: BoxConstraints(
          maxHeight: widget.textHeight, maxWidth: widget.textWidth),
      child: Column(
        children: [
          Container(
            padding: EdgeInsets.zero,
            decoration: _inputDecoration,
            margin: EdgeInsets.zero,
            child: ConstrainedBox(
                constraints: BoxConstraints(
                    maxHeight: maxHeight, maxWidth: widget.textWidth),
                child: TextField(
                  autofocus: false,
                  autocorrect: true,
                  enableInteractiveSelection: false,
                  obscureText: widget.obscureText,
                  focusNode: _focusNode,
                  controller: _textEditingController,
                  textCapitalization: TextCapitalization.characters,
                  textAlignVertical: TextAlignVertical.center,
                  style: TextStyle(
                      textBaseline: TextBaseline.alphabetic,
                      height: _textHeight,
                      fontSize: maxHeight * _textFontScale * _textScale),
                  decoration: InputDecoration(
                    isCollapsed: true,
                    prefixIcon: null != widget.preIcon
                        ? Icon(
                            widget.preIcon,
                            size: maxHeight * _textFontScale * _textScale,
                          )
                        : null,
                    suffixIcon: _textEditingController.value.text != null &&
                            _textEditingController.value.text != ""
                        ? InkWell(
                            child: Icon(
                              Icons.clear,
                              color: Colors.red,
                              size: widget.textHeight *
                                  _scale *
                                  _textFontScale *
                                  _textScale,
                            ),
                            onTap: () {
                              _focusNode.unfocus();
                              _focusNode.canRequestFocus = false;
                              Future.delayed(Duration(milliseconds: 200), () {
                                _focusNode.canRequestFocus = true;
                              });
                              _textEditingController.text = "";
                              setState(() {});
                            },
                          )
                        : null,
                    hintText: widget.hintText,
                    hintMaxLines: 1,
                    hintStyle: TextStyle(
                        textBaseline: TextBaseline.alphabetic,
                        height: _textHeight,
                        fontSize: widget.textHeight *
                            _scale *
                            _textFontScale *
                            _textScale),
                    fillColor: Colors.black.withOpacity(0.5),
                    contentPadding: EdgeInsets.only(top: 0, bottom: 0),
                    border: OutlineInputBorder(borderSide: BorderSide.none),
                  ),
                )),
          ),
          widget.showError
              ? Expanded(
                  child: (widget.textFiledValidata != null &&
                              widget.textFiledValidata.show &&
                              !RegExp(widget.textFiledValidata.paretten)
                                  .hasMatch(_textEditingController.text)) ||
                          (widget.textFiledValidata != null &&
                              null != widget.textFiledValidata.error)
                      ? Container(
                          alignment: Alignment.centerLeft,
                          child: Text(
                            widget.textFiledValidata.error != null
                                ? widget.textFiledValidata.error
                                : widget.textFiledValidata.tips,
                            style: TextStyle(
                                color: Colors.red,
                                height: _textHeight,
                                fontSize: widget.textHeight *
                                    _tipScale *
                                    _textFontScale),
                            textAlign: TextAlign.right,
                          ))
                      : Container())
              : SizedBox()
        ],
      ),
    );
  }
}

class IFloatText extends StatefulWidget {
  final TextEditingController parentController;
  final TextFiledValidata textFiledValidata;
  final String hintText;
  final IconData preIcon;
  final double textWidth;
  final double textHeight;
  final bool obscureText;
  final String defaultStr;
  IFloatText(
      {this.parentController,
      this.textFiledValidata,
      this.obscureText = false,
      this.hintText,
      this.preIcon,
      this.defaultStr,
      this.textWidth,
      this.textHeight});
  @override
  _IFloatTextState createState() => _IFloatTextState();
}

class _IFloatTextState extends State<IFloatText> {
  TextEditingController _bottomSheetEditingController;

  FocusNode _bottomSheeFocusNode = FocusNode();

  void initData() {
    _bottomSheeFocusNode.unfocus();
    widget.parentController.text = _bottomSheetEditingController.text;
    if (null != widget.textFiledValidata) {
      widget.textFiledValidata.show = true;
      if (null != widget.textFiledValidata.paretten) {
        widget.textFiledValidata.success =
            RegExp(widget.textFiledValidata.paretten)
                .hasMatch(_bottomSheetEditingController.text);
      }
      widget.textFiledValidata.value = _bottomSheetEditingController.text;
    }
    Navigator.of(context).pop();
  }

  @override
  void dispose() {
    _bottomSheeFocusNode.dispose();
    _bottomSheetEditingController.dispose();
    super.dispose();
  }

  @override
  void initState() {
    _bottomSheetEditingController = TextEditingController.fromValue(
        TextEditingValue(
            text: widget.parentController.text, //判断keyword是否为空
            selection: TextSelection.fromPosition(TextPosition(
                affinity: TextAffinity.downstream,
                offset: widget.parentController.text.length))));

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
        child: Material(
            color: Colors.transparent,
            child: GestureDetector(
                child: Container(
                    color: Colors.white.withOpacity(0.2),
                    child: Align(
                        alignment: Alignment.topLeft,
                        child: Container(
                            color: Colors.white,
                            constraints: BoxConstraints(
                                maxHeight: widget.textHeight,
                                maxWidth: MediaQuery.of(context).size.width),
                            alignment: Alignment.center,
                            child: TextField(
                              autofocus: true,
                              autocorrect: true,
                              obscureText: widget.obscureText,
                              focusNode: _bottomSheeFocusNode,
                              controller: _bottomSheetEditingController,
                              decoration: InputDecoration(
                                contentPadding:
                                    EdgeInsets.only(top: 0, bottom: 0),
                                hintText: widget.hintText,
                                border: InputBorder.none,
                                hintStyle: TextStyle(
                                    textBaseline: TextBaseline.alphabetic,
                                    height: _textHeight,
                                    fontSize:
                                        widget.textHeight * _textFontScale),
                                isCollapsed: true,
                              ),
                              style: TextStyle(
                                  textBaseline: TextBaseline.alphabetic,
                                  height: _textHeight,
                                  fontSize: widget.textHeight * _textFontScale),
                              onSubmitted: (val) {
                                initData();
                              },
                              onChanged: (val) {
                                if (null != widget.textFiledValidata &&
                                    null != widget.textFiledValidata.paretten) {
                                  widget.textFiledValidata.show = true;
                                  if (null !=
                                      widget.textFiledValidata.paretten) {
                                    widget.textFiledValidata.success = RegExp(
                                            widget.textFiledValidata.paretten)
                                        .hasMatch(val);
                                  }
                                  widget.textFiledValidata.value = val;
                                }
                                widget.parentController.text = val;
                              },
                            )))),
                onTap: () {
                  initData();
                })),
        onWillPop: () async {
          initData();
          return true;
        });
  }
}

class TextFiledValidata {
  String value;
  String paretten;
  String tips;
  String error;
  bool show;
  bool success;

  TextFiledValidata();

  bool check() {
    this.show = true;
    return this.success;
  }

  TextFiledValidata.init(
      {this.paretten,
      this.tips,
      this.show = false,
      this.value,
      this.success = false,
      this.error});
}
